package bsh;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import bsh.meta.FieldDescriptor;
import bsh.utils.reflection.OpenClassLoader;

/**
 * Plain implementation of a {@link LoadedTrait}
 * 
 * @author takeshi
 */
public class LoadedTraitImpl implements LoadedTrait {
    private final Trait delegate;

    private final Class<?> traitInterface;

    private final Class<?> implementor;

    private final List<LoadedTrait> loadedTraits;

    /**
     * Constructor
     * 
     * @param delegate the delegate
     * @param traitInterface the trait interface
     * @param implementor the implementor class
     * @param loadedTraits the list of loaded traits
     */
    public LoadedTraitImpl(Trait delegate, Class<?> traitInterface, Class<?> implementor, List<LoadedTrait> loadedTraits) {
        super();
        this.delegate = delegate;
        this.traitInterface = traitInterface;
        this.implementor = implementor;
        this.loadedTraits = new ArrayList<LoadedTrait>(loadedTraits);
    }

    /**
     * {@inheritDoc}
     */
    public List<BytecodeGenerator> instanceInitializers() {
        return delegate.instanceInitializers();
    }

    /**
     * {@inheritDoc}
     */
    public List<FieldDescriptor> instanceFields() {
        return delegate.instanceFields();
    }

    /**
     * {@inheritDoc}
     */
    public List<LoadedTrait> implementedTraits() {
        return loadedTraits;
    }

    /**
     * {@inheritDoc}
     */
    public Class<?> traitInterface() {
        return this.traitInterface;
    }

    /**
     * {@inheritDoc}
     */
    public Class<?> implementor() {
        return this.implementor;
    }

    /**
     * {@inheritDoc}
     */
    public LoadedTrait load(OpenClassLoader loader) {
        if (this.implementor.getClassLoader().equals(loader)) {
            return this;
        }
        return this.delegate.load(loader);
    }

    /**
     * {@inheritDoc}
     */
    public Map<String, Class<?>> allTypeImports() {
        return delegate.allTypeImports();
    }

    /**
     * {@inheritDoc}
     */
    public Collection<? extends String> allWildcardImports() {
        return delegate.allWildcardImports();
    }

}